<?php
/**
 * +----------------------------------------------------------------------
 * | UniAdmin [ 渐进式模块化通用后台 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2018-2020 http://uniadmin.jiangruyi.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 * +----------------------------------------------------------------------
 * | Author: jry <ijry@qq.com>
 * +----------------------------------------------------------------------
*/

namespace plugin\admin\app\common\xbuilder;

use plugin\admin\app\common\xbuilder\widget\NodeTree;

class XBuilderList {
    // 数据
    private $data =  [
        'title'=>'',
        'remark'=>'',
        'type'=>'page',
        "toolbar"=> [],
        'body'=>[
            "type"=>"crud", /*列表组件*/
            "name"=>"crud", /*列表名称*/
            "defaultParams"=>[
                'perPage'=>15
            ],
            "headerToolbar"=>[
                'statistics',
                'bulkActions'
            ],
            'syncLocation'=>false,
            'bulkActions'=>[],
            'columns'=>[], /*列表数据*/
        ],
    ];
    private $_table_data_list; // 表格数据分页
    private $_table_data_list_key = 'id'; // 表格数据列表主键字段名
    private $_template = ''; // 模版
    private $_right_button_list  = [];  //每行表格中的右侧按钮
    private $_hove_right_button  = false;  //hove显示右侧按钮
    private $_tab_nav  = [];  //tabs切换框数据

    public function __construct()
    {
        $this->_template = 'temple/list';
        return $this;
    }
    /**
     * @param $title
     * @param $data
     * @return $this
     */
    public function setTabNav($title, $data)
    {
        if(is_array($title)){
            $this->_tab_nav = $title;
        } else {
            $this->_tab_nav[] = [
                'title'=>$title,
                'body'=>$data
            ];
        }
        return $this;
    }
    /**
     * 设置标题
     * @param $meta_title
     */
    public function setMetaTitle($meta_title)
    {
        $this->data['title'] = $meta_title;
        return $this;
    }

    /**
     * 设置注解
     * @param $tips
     * @return $this
     */
    public function setTitleTips($tips)
    {
        $this->data['remark'] = $tips;
        return $this;
    }
    /**
     * 表格数据列表的主键名称
     *
     */
    public function setTableDataListKey($table_data_list_key)
    {
        $this->_table_data_list_key = $table_data_list_key;
        return $this;
    }

    /**
     * 设置页面模版
     * @param $template 模版
     * @return $this
     *
     */
    public function setTemplate($template)
    {
        $this->_template = $template;
        return $this;
    }

    /**
     * @param $name
     * @param $title
     * @param null $type text,audio(音频),carousel(轮播图),image,date(日期),progress(进度),status,switch(开关),mapping(映射-TODO),list(列表),json
     * @param false $isSearch (字段是否搜索，默认不搜索)
     * @param false $isSort （字段是否排序，默认不排序）
     * @param null $param （补充字段 ['attrName'=>'attrValue']）
     * @return $this
     */
    public function addTableColumn($name, $title, $type = null, $isSearch = false,$isSort = false)
    {
        $param = is_array($type) ? $type : ['type'=>$type];
        $column = [
            'name'  => $name,
            'label' => $title
        ];
        if($isSearch){
            $column['searchable'] = $isSearch;
        }
        if($isSort){
            $column['sortable'] = $isSort;
        }
        if(isset($column['sortable'])){
            $column['searchable'] = false;
        }
        if ($type) {
            $column = array_merge($column, $param);
        }
        $this->data['body']['columns'][] = $column;
        return $this;
    }
    public function setRightHover($isHover = false)
    {
        $this->_hove_right_button = $isHover;
        return $this;
    }

    protected function _buttonTypeMap($type,$isGroup = false){
        $groupMsg = $isGroup ? '批量' : '';
        $typeMap = [
            [
                'type'=>'delete',
                'label'=>$groupMsg . '删除',
                'visibleOn'=>"true",
                'confirmText'=>'确定要'.$groupMsg.'删除?'
            ],
            [
                'type'=>'forbid',
                'value'=>0,
                'label'=>$groupMsg . '禁用',
                'visibleOn'=>"this.status == 1",
                'confirmText'=>'确定要'.$groupMsg.'禁用?'
            ],
            [
                'type'=>'resume',
                'value'=>1,
                'label'=>$groupMsg . '启用',
                'visibleOn'=>"this.status == 0",
                'confirmText'=>'确定要'.$groupMsg.'启用?'
            ],
            [
                'type'=>'recycle',
                'value'=>-1,
                'label'=>$groupMsg . '回收',
                'visibleOn'=>"this.status == 1 || this.status == 0",
                'confirmText'=>'确定要'.$groupMsg.'回收?'
            ],
            [
                'type'=>'restore',
                'value'=>1,
                'label'=>$groupMsg . '还原',
                'visibleOn'=>"this.status == -1",
                'confirmText'=>'确定要'.$groupMsg.'还原?'
            ],
        ];
        $tree = new NodeTree($typeMap);
        return $tree->where(['type'=>$type])->find();
    }
    /**
     * @param $type $edit,delete,forbid,resume,recycle,restore
     * @param null $attribute
     * $type = 'edit'   // edit,'delete','forbid','resume','recycle','restore'
    $type = [
    'type'=>'button',
    'url'=>'admin/index/api',
    'label'=>'',
    'confirmText'=>''
    ]
     */
    public function addRightButton($type, $attribute = null){
        $this->_right_button_list['label'] = '操作';
        $this->_right_button_list['type'] = 'operation';
        $common_button_type = ['delete','forbid','resume','recycle','restore']; //通用操作类型
        switch ($type) {
            case 'edit': // 添加新增按钮
                // 预定义按钮属性以简化使用
                $button_attribute['label'] = '修改';
                $button_attribute['type'] = 'button';
                $button_attribute['level'] = 'primary';
                $button_attribute['actionType'] = 'dialog';
                if ($attribute && is_array($attribute)) {
                    $title = $attribute['title'];
                    $attribute['title'] = '';
                    $dialog = [
                        'actionType'=>'dialog',
                        'dialog'=>[
                            'size'=>'md',
                            'title'=>$title,
                            'body'=>$attribute
                        ]
                    ];
                    $button_attribute = array_merge($button_attribute, $dialog);
                }
                break;
            case in_array($type,$common_button_type):
                $filterType = $this->_buttonTypeMap($type);
                if(!$filterType) break;
                $button_attribute['label'] = $filterType['label'];
                $button_attribute['type'] = 'button';
                $button_attribute['level'] = 'danger';
                $button_attribute['reload'] = 'crud';
                $button_attribute['confirmText'] = $filterType['confirmText'];
                $button_attribute['visibleOn'] = $filterType['visibleOn'];
                $button_attribute['actionType'] = 'ajax';
                $button_attribute['model'] = $attribute['model'] ?? '';
                $button_attribute['api'] = [
                    'method'=>'post',
                    'headers'=>[
                        'X-Requested-With'=>'XMLHttpRequest'
                    ],
                    'data' => [   //只提交变更字段
                        'diff' => "\${diff}"
                    ],
                    'url'=>get_curent_path('api') . '/setStatus?ids=${id}' . "&status={$filterType['type']}&model=". urlencode($button_attribute['model'])
                ];
                if ($attribute && is_array($attribute) && !$attribute['url']) {
                    $button_attribute = array_merge($button_attribute, $attribute);
                }
                break;
                // 自定义按钮
            case isset($type['type']) && $type['type'] === 'button':
                $button_attribute['label'] = $type['label'];
                $button_attribute['type'] = 'button';
                $button_attribute['reload'] = 'crud';
                $button_attribute['confirmText'] = $type['confirmText'];
                $button_attribute['actionType'] = 'ajax';
                $button_attribute['model'] = $type['model'] ?? '';
                $button_attribute['api'] = [
                    'method'=>'post',
                    'headers'=>[
                        'X-Requested-With'=>'XMLHttpRequest'
                    ],
                    'url'=>(string)$type['url'] . '?ids=${id}'
                ];
                if (is_array($type)) {
                    $button_attribute = array_merge($button_attribute, $type);
                }
                break;
            default : break;
        }
        if ($attribute && is_array($attribute) && !$type === 'edit') {
            $button_attribute = array_merge($button_attribute, $attribute);
        }
        $this->_right_button_list['buttons'][] = $button_attribute;
        return $this;
    }
    /**
     * 表格数据列表
     *
     */
    public function setTableDataList($table_data_list)
    {
        $is_page=is_callable([$table_data_list,'render']);
        if($is_page){
            $table_data=$table_data_list->toArray();
            $this->_table_data_list = $table_data['data'];
        }else{
            $table_data=$table_data_list->toArray();
            $this->_table_data_list=$table_data;
        }
        return $this;
    }

    public function setTableApi($url ='',$method = 'get',$cache = 2000){
        $this->data['body']['api'] = [
            'url'=>(string)$url ?: get_curent_path('api') . '/getApiTableData',
            'method'=>$method,
            'cache'=>$cache,
            'headers'=>[
                'X-Requested-With'=>'XMLHttpRequest'
            ]
        ];
        return $this;
    }
    public static function handleTableData($table_data_list,$isCollection = true)
    {
        $is_page=is_callable([$table_data_list,'render']);
        $table_data = $isCollection ? $table_data_list->toArray() :  $table_data_list;
        if($is_page){
            $returnData['items'] = $table_data['data'];
            $returnData['total'] = $table_data['total'];
        }else{
            $returnData['items'] = $table_data;
        }
        return $returnData;
    }

    public function addTopExport(){
        $headerToolbar = $this->data['body']['headerToolbar'];
        if(!in_array("Glenn",$headerToolbar)){
            $this->data['body']['headerToolbar'][] = 'export-csv';
        }
        return $this;
    }
    /**
     * @param $type add,resume,forbid,recycle,restore,delete
     * @param array $attribute ['model'=>'模型名','label' => '换个马甲','url' => 'https://www.qq.com','type' => 'button','level' => 'info','actionType' => 'url']
     * @return $this
     */
    public function addTopButton($type, $attribute = null){
        switch ($type) {
            case 'add': // 添加新增按钮
                // 预定义按钮属性以简化使用
                $my_attribute['label'] = '新增';
                $my_attribute['type'] = 'button';
                $my_attribute['level'] = 'info';
                $my_attribute['actionType'] = 'dialog';
                if ($attribute && is_array($attribute)) {
                    $title = $attribute['title'];
                    $attribute['title'] = '';
                    $dialog = [
                        'actionType'=>'dialog',
                        'dialog'=>[
                            'size'=>'md',
                            'title'=>$title,
                            'body'=>$attribute
                        ]
                    ];
                    $my_attribute = array_merge($my_attribute, $dialog);
                }

                // 这个按钮定义好了把它丢进按钮池里
                $this->data['toolbar'][] = $my_attribute;
                break;
            default :
                $filterType = $this->_buttonTypeMap($type,true);
                if(!$filterType) break;
                $my_attribute['label'] = $filterType['label'];
                $my_attribute['type'] = 'button';
                $my_attribute['confirmText'] = $filterType['confirmText'];
                $my_attribute['actionType'] = 'ajax';
                $my_attribute['reload'] = 'crud';
                $my_attribute['model'] = $attribute['model'] ?? '';
                $my_attribute['api'] = [
                    'method'=>'post',
                    'headers'=>[
                        'X-Requested-With'=>'XMLHttpRequest'
                    ],
                    'data' => [   //只提交变更字段
                        'ids' => "\${ids}"
                    ],
                    'url'=>get_curent_path('api') . '/setStatus?status=' . $filterType['type'] . '&model=' . urlencode($my_attribute['model'])
                ];
                // 如果定义了属性数组则与默认的进行合并，详细使用方法参考上面的新增按钮
                if ($attribute && is_array($attribute)) {
                    $my_attribute = array_merge($my_attribute, $attribute);
                }
                $this->data['body']['bulkActions'][] = $my_attribute;
                break;
        }
        return $this;
    }

    /**
     * 获取页面配置数据
     * @return mixed
     */
    public function getPageData(){
        if(!empty($this->_right_button_list)){
            if($this->_hove_right_button){
                $this->data['body']['itemActions'] = $this->_right_button_list['buttons'];
            } else {
                $this->data['body']['columns'][] = $this->_right_button_list;
            }
        }
        return json(['code' => 0, 'data' => $this->data, 'msg' => 'ok']);
//        return $this->data;
    }
    public function display()
    {
        $pageConfig = $this->getPageData();
//        halt($pageConfig);
        if(!empty($this->_tab_nav)){
            $tabKey = request()->get('tab_key', 0);
            $pageConfig = [
                'title'=>'',
                'type'=>'page',
                'body'=>[
                    'title'=>'',
                    'type'=>'tabs',
                    "activeKey"=>$tabKey,
                    'mode'=>'line',
                    'tabs'=>$this->_tab_nav
                ]
            ];
        }
        return view($this->_template,['pageConfigs'=>$pageConfig, 'meta_title'=>$pageConfig['title']],'common');
    }
}
